package chapter02.d07;
/**
 * 内存占用地，效率高，线程安全，多线程操作原子性。
 * @author kenneth
 *
 */
public class Singleton4 {
	// 定义一个私有构造方法
	private Singleton4() {

	}

	// 定义一个静态私有变量(不初始化，不使用final关键字，使用volatile保证了多线程访问时instance变量的可见性，避免了instance初始化时其他变量属性还没赋值完时，被另外线程调用)
	private static volatile Singleton4 instance;

	// 定义一个共有的静态方法，返回该类型实例
	public static Singleton4 getIstance() {
		// 对象实例化时与否判断（不使用同步代码块，instance不等于null时，直接返回对象，提高运行效率）
		if (instance == null) {
			// 同步代码块（对象未初始化时，使用同步代码块，保证多线程访问时对象在第一次创建后，不再重复被创建）
			synchronized (Singleton4.class) {
				// 未初始化，则初始instance变量
				if (instance == null) {
					instance = new Singleton4();
				}
			}
		}
		return instance;
	}
}
/*
 使用volatile的原因
1.为对象分配内存
2.初始化实例对象
3.把引用instance指向分配的内存空间
这个三个步骤并不能保证按序执行，处理器会进行指令重排序优化，存在这样的情况：
优化重排后执行顺序为：1,3,2, 这样在线程1执行到3时，instance已经不为null了，线程2此时判断instance!=null，则直接返回instance引用，但现在实例对象还没有初始化完毕，此时线程2使用instance可能会造成程序崩溃。
现在要解决的问题就是怎样限制处理器进行指令优化重排。
 
 
 
 */
